var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/functionalComponent/table/editor/factory.tsx
var factory_exports = {};
__export(factory_exports, {
  EditorFactory: () => EditorFactory
});
module.exports = __toCommonJS(factory_exports);
var import_react = require("react");
var import_baseComponent = require("../../../baseComponent");
var import_util = require("../util");
var import_useValue = require("../hook/useValue");
var import_helpRef = require("./helpRef");
var ROW_CMP = Symbol("rowCmp");
var REQUEST_DATA = Symbol("requestData");
var waitDelay = 1e3 / 60;
var editorRef = {
  select: { Editor: SelectEditor, waitDelay },
  datepicker: { Editor: DatePickerEditor, waitDelay },
  datetimepicker: { Editor: DatePickerEditor, waitDelay, props: { type: "datetime" } },
  timepicker: { Editor: DatePickerEditor, waitDelay },
  checkbox: { Editor: CheckBoxEditor, waitDelay },
  switch: { Editor: CheckBoxEditor, waitDelay, props: { type: "switch" } },
  help: { Editor: HelpEditor, waitDelay },
  radiogroup: { Editor: OptionsEditor, waitDelay },
  checkboxgroup: { Editor: OptionsEditor, waitDelay }
};
function isElementType(type) {
  if (typeof type === "function")
    return true;
  return !!(type && typeof type === "object" && type.render && type.$$typeof);
}
function getEditor(xType = "text") {
  let editor = isElementType(xType) ? Customized : editorRef[xType.toLowerCase()];
  if (!editor && import_util.util.isString(xType)) {
    const [Cmp, defaultProps, extendObj] = (0, import_util.getRegisterComponentWithProps)(xType);
    editor = Cmp ? extendObj.isHelp ? editorRef.help : Customized : TextEditor;
    if (Cmp) {
      editor.props = { ...editor.props, ...defaultProps };
    }
  }
  if (editor == null ? void 0 : editor.Editor) {
    return [editor.Editor, editor.waitDelay, editor.props];
  }
  return [editor || TextEditor];
}
function getOptions(editor, editRef, isDisabled = false, editProps) {
  var _a, _b;
  const {
    type,
    min,
    max,
    step,
    maxLength,
    antProps,
    required,
    listeners,
    hidden,
    disabled,
    regExp,
    xtype,
    dateFormat,
    displayField,
    nameField,
    cache,
    canCancelChecked,
    incompatible,
    ...others
  } = editor;
  const props = {
    ref: editRef,
    style: {
      width: "100%",
      height: "100%",
      border: 0,
      borderRadius: 0,
      borderColor: "transparent"
    },
    autoFocus: true,
    disabled: isDisabled,
    ...others,
    ...antProps
  };
  if (type !== void 0) {
    props.type = type;
  } else if ((_a = (0, import_util.getRegisterComponentWithProps)(xtype)[2]) == null ? void 0 : _a.isHelp) {
    props.type = xtype;
  }
  if (min !== void 0) {
    props.min = min;
  }
  if (max !== void 0) {
    props.max = max;
  }
  if (step !== void 0) {
    props.step = step;
  }
  if (maxLength !== void 0) {
    props.maxLength = maxLength;
  }
  return { ...editProps, ...editor, props, xType: (_b = xtype == null ? void 0 : xtype.toLowerCase) == null ? void 0 : _b.call(xtype) };
}
var syEditor = Symbol("__originEditor__");
function syncColumnEditor(column, newEditor) {
  column.editor[syEditor] = column.editor[syEditor] || { ...column.editor };
  column.editor = { ...column.editor[syEditor], [syEditor]: column.editor[syEditor] };
  Object.keys(newEditor).forEach((k) => {
    column.editor[k] = newEditor[k];
  });
}
var EditorFactory = (props) => {
  var _a;
  const { column, children = void 0, table, editing = false, style, ...others } = props;
  const { dataIndex, editor } = column;
  if ((_a = editor.hidden) == null ? void 0 : _a.call(editor, { row: others.row, dataIndex })) {
    return null;
  }
  if (children && (!editing || table.isDisabled({ row: others.row, dataIndex, column }))) {
    return children;
  }
  return /* @__PURE__ */ React.createElement(Editing, { editing, style, others, table, dataIndex, column }, children);
};
function Editing({ editing, column, table, dataIndex, children, style, others }) {
  const initRet = (0, import_react.useMemo)(() => {
    var _a, _b, _c;
    return editing && ((_c = (_b = (_a = column.editor) == null ? void 0 : _a.listeners) == null ? void 0 : _b.onBeforeInit) == null ? void 0 : _c.call(_b, {
      editor: column.editor,
      row: others.row,
      dataIndex,
      table: others.table
    }));
  }, [editing]);
  if (initRet !== false) {
    const newEditor = (0, import_helpRef.createEditorProps)(initRet ? { ...column.editor, ...initRet } : column.editor);
    syncColumnEditor(column, { ...initRet });
    return /* @__PURE__ */ React.createElement(
      "div",
      {
        style: { height: "100%", width: "100%", display: "flex", alignItems: "center", ...style },
        onClick: import_util.stopPropagation
      },
      /* @__PURE__ */ React.createElement(Editor, { table, column, editor: newEditor, ...others })
    );
  }
  return /* @__PURE__ */ React.createElement("div", { className: "editor-disabled cell-active" }, children);
}
function Editor({ column, editor, row, table, rendered = false, ...others }) {
  const rowIndex = table.getRowIndex(row);
  const editRef = (0, import_react.useRef)();
  const { dataIndex, dataIndexField } = column;
  const di = dataIndexField || dataIndex;
  const [EditorCmp, changeWait, editProps] = getEditor(editor.xtype);
  const lastRow = { ...row };
  const onKeyDownCallback = (0, import_util.useRefCallback)((e) => {
    var _a;
    if (e.keyCode !== 9 && ((_a = editRef.current) == null ? void 0 : _a.stopPropagation)) {
      (0, import_util.stopPropagation)(e);
    }
  });
  const onChangeCallback = (0, import_util.useDebounce)(
    async (currentValue) => {
      var _a, _b, _c, _d, _e;
      import_util.util.setObjValue(row, di, currentValue);
      const originValue = ((_c = (_a = editRef.current) == null ? void 0 : (_b = _a.getApi()).getOrigin) == null ? void 0 : _c.call(_b)) ?? currentValue;
      row.__update__ = { rowIndex, dataIndex, value: currentValue, originValue, lastRow };
      if ((column == null ? void 0 : column.levelSummary) && table.props.isTree) {
        table.updateParent(
          row,
          (r) => import_util.util.setObjValue(
            r,
            di,
            import_util.util.numberPrecision(
              r.children.reduce((p, c) => {
                return p + import_util.util.getObjValue(c, di, 0);
              }, 0)
            )
          )
        );
      }
      await ((_e = (_d = editor.listeners) == null ? void 0 : _d.onChange) == null ? void 0 : _e.call(_d, {
        value: currentValue,
        row,
        lastRow,
        rowIndex,
        table,
        dataIndex,
        getEditor: (dataIndex2) => {
          var _a2;
          return ((_a2 = row[ROW_CMP]) == null ? void 0 : _a2[dataIndex2]) ?? editRef.current;
        },
        originValue
      }));
      table.updateRowDataByIndex(rowIndex, row, true);
      if (rendered) {
        table.endEditing(true);
      }
    },
    { immediate: false, wait: changeWait || 250 }
  );
  const [value, setValue] = (0, import_useValue.useValue)(import_util.util.getObjValue(row, di), EditorCmp === HelpEditor);
  (0, import_react.useEffect)(() => {
    if (editRef.current) {
      if (rendered) {
        row[ROW_CMP] = row[ROW_CMP] || {};
        row[ROW_CMP][column.dataIndex] = editRef.current;
      } else {
        table.notify(editRef.current, "activeEditor").then();
      }
    }
    return () => {
      if (row[ROW_CMP]) {
        delete row[ROW_CMP][column.dataIndex];
      }
    };
  }, [editor.xtype, row, column]);
  (0, import_react.useEffect)(() => {
    var _a, _b;
    if (editRef.current) {
      (_b = (_a = editor.listeners) == null ? void 0 : _a.onInit) == null ? void 0 : _b.call(_a, {
        editor: editRef.current,
        row,
        rowIndex,
        dataIndex,
        table
      });
    }
  }, []);
  const onChangeHandler = (0, import_util.useRefCallback)((...args) => {
    var _a;
    let [currentValue1, currentValue2] = [void 0, void 0];
    const api = (_a = editRef.current) == null ? void 0 : _a.getApi();
    if (api == null ? void 0 : api.getValue) {
      currentValue1 = api.getValue(",");
      currentValue2 = api.getRawValue ? api.getRawValue() : api.getValue();
    } else if (args.length > 0) {
      const e = args[0];
      currentValue1 = (e == null ? void 0 : e.target) ? e.target.value : e;
      currentValue2 = currentValue1;
    }
    setValue(currentValue2, () => {
      onChangeCallback(currentValue1);
    });
  });
  return EditorCmp && /* @__PURE__ */ React.createElement(
    EditorCmp,
    {
      editorOptions: getOptions(editor, editRef, table.isDisabled({ row, dataIndex, column }), editProps),
      value,
      table,
      onKeyDown: onKeyDownCallback,
      onChange: onChangeHandler,
      outRef: editRef,
      column,
      dataIndex: di,
      row,
      ...others
    }
  );
}
function TextEditor({ editorOptions, value, outRef, onChange }) {
  const { type = "text", xType, props } = editorOptions;
  const Comp = xType === "inputnumber" || ["number", "amount", "amt", "qty", "prc", "rate", "percent"].includes(type) ? import_baseComponent.InputNumber : xType === "textarea" || type === "textarea" ? import_baseComponent.TextArea : import_baseComponent.Input;
  props.type = type;
  if (Comp === import_baseComponent.InputNumber) {
    props.keyboard = false;
    if (type === "rate") {
      props.suffix = "%";
    }
  }
  (0, import_react.useEffect)(() => {
    var _a, _b;
    const api = (_a = outRef.current) == null ? void 0 : _a.getApi();
    if (api == null ? void 0 : api.select) {
      api == null ? void 0 : api.select();
    } else {
      (_b = api == null ? void 0 : api.focus) == null ? void 0 : _b.call(api, {
        cursor: "all"
      });
    }
  }, []);
  return /* @__PURE__ */ React.createElement(Comp, { ...props, allowClear: true, autoComplete: "off", value, onChange });
}
function CheckBoxEditor(defaultProps) {
  const { type = "checkbox", xType } = defaultProps.editorOptions;
  const Comp = xType === "switch" || type === "switch" ? import_baseComponent.Switch : import_baseComponent.Checkbox;
  return /* @__PURE__ */ React.createElement(Comp, { ...getEditorProps("check", defaultProps) });
}
function getCheckProps(defaultProps) {
  const { editorOptions, value, onChange, table, dataIndex } = defaultProps;
  const {
    incompatible = false,
    canCancelChecked = false,
    props: { style, ...others }
  } = editorOptions;
  const { checkedValue = true, unCheckedValue = false } = others;
  const onChangeHandler = (val) => {
    if (incompatible) {
      if (val === checkedValue) {
        const rows = table.getRows();
        rows.forEach((r, i) => {
          if (import_util.util.getObjValue(r, dataIndex) === checkedValue) {
            import_util.util.setObjValue(r, dataIndex, unCheckedValue);
            r.__update__ = { dataIndex, value: unCheckedValue };
          }
        });
        onChange(checkedValue);
        return true;
      } else if (canCancelChecked) {
        onChange(unCheckedValue);
        return true;
      }
      return false;
    } else {
      onChange(val);
    }
  };
  return { ...others, autoFocus: false, value, onChange: onChangeHandler };
}
function OptionsEditor(defaultProps) {
  const { xType } = defaultProps.editorOptions;
  const Comp = xType === "checkboxgroup" ? import_baseComponent.CheckboxGroup : import_baseComponent.RadioGroup;
  return /* @__PURE__ */ React.createElement("div", { style: { overflow: "auto", height: "100%", display: "flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(Comp, { ...getEditorProps("options", defaultProps) }));
}
function getOptionsProps(defaultProps) {
  const { editorOptions, value, onChange } = defaultProps;
  const {
    props: { style, ...others }
  } = editorOptions;
  return { ...others, autoFocus: false, value, onChange };
}
function getValueLabel({ row, value, valueType, nameField, multiple }) {
  if (import_util.util.isNullOrEmpty(value)) {
    return multiple ? void 0 : import_util.util.convertData(value, valueType);
  }
  const splitStr = ",";
  const defaultLabel = row.hasOwnProperty(nameField) ? row[nameField] : "";
  const label = row.hasOwnProperty(nameField) ? row[nameField] ?? "" : value;
  let valueLabel;
  if (multiple && !import_util.util.isNullOrEmpty(value)) {
    const labelArray = import_util.util.isArray(label) ? label : label ? label.toString().split(splitStr) : [];
    const valueArray = import_util.util.isArray(value) ? value : value.toString().split(splitStr);
    valueLabel = valueArray.map((v, i) => {
      return (v == null ? void 0 : v.hasOwnProperty("value")) ? v : {
        value: import_util.util.convertData(v, valueType),
        label: labelArray[i] ?? defaultLabel
      };
    }).filter(({ label: label2 }) => !import_util.util.isNullOrEmpty(label2, ""));
    if ((valueLabel == null ? void 0 : valueLabel.length) === 0) {
      valueLabel = null;
    }
  } else {
    valueLabel = value.hasOwnProperty("value") ? value : {
      value: import_util.util.convertData(value, valueType),
      label
    };
  }
  return valueLabel;
}
function SelectEditor(defaultProps) {
  const {
    editorOptions: { request },
    column: { editor },
    row
  } = defaultProps;
  (0, import_react.useEffect)(() => {
    defaultProps.outRef.current && (defaultProps.outRef.current.editing = true);
  }, []);
  const newProps = getEditorProps("select", defaultProps);
  const refRequest = (0, import_react.useCallback)(async () => {
    if (request) {
      if (editor.cache && editor[REQUEST_DATA]) {
        return editor[REQUEST_DATA];
      }
      editor[REQUEST_DATA] = await request(row);
      return editor[REQUEST_DATA];
    }
  }, [request, row]);
  if (request) {
    newProps.request = refRequest;
  }
  return /* @__PURE__ */ React.createElement(import_baseComponent.Select, { ...newProps });
}
function getSelectProps(defaultProps) {
  const {
    editorOptions,
    dataIndex,
    column: { valueType },
    value,
    row,
    outRef,
    onChange,
    onKeyDown
  } = defaultProps;
  const { multiple, data, valueField, labelField, nameField, props } = editorOptions;
  const displayField = nameField || editorOptions.displayField || `${dataIndex}EXName`;
  const newProps = {
    showSearch: true,
    allowClear: true,
    maxTagCount: multiple ? "responsive" : void 0,
    ...props,
    value: getValueLabel({ row, value, valueType, nameField: displayField, multiple }),
    autoComplete: "off",
    defaultOpen: true,
    data,
    filterOption: (input, { value: value2, children, label }) => {
      input = input.toLowerCase();
      const text = children ?? label ?? "";
      return value2 && (value2 + "").toLowerCase().indexOf(input) >= 0 || text && (text + "").toLowerCase().indexOf(input) >= 0;
    },
    mode: multiple ? "multiple" : void 0
  };
  delete newProps.multiple;
  if (valueField) {
    newProps.valueField = valueField;
  }
  if (labelField) {
    newProps.labelField = labelField;
  }
  newProps.onChange = (...args) => {
    var _a;
    const api = (_a = outRef.current) == null ? void 0 : _a.getApi();
    if (api) {
      if (api.getText && dataIndex !== displayField) {
        row[displayField] = api.getText(",");
      }
      onChange();
    } else {
      onChange(...args);
    }
  };
  newProps.onDropdownVisibleChange = (open) => {
    outRef.current && (outRef.current.editing = open);
  };
  newProps.onKeyDown = (e) => {
    const keyCodes = [9, 35, 36, 37, 39];
    if (keyCodes.includes(e.keyCode)) {
      outRef.current && (outRef.current.stopPropagation = false);
    }
    onKeyDown(e);
  };
  newProps.onInputKeyDown = () => {
    outRef.current && (outRef.current.stopPropagation = outRef.current.editing);
  };
  return newProps;
}
function DatePickerEditor(defaultProps) {
  const { type, xType } = defaultProps.editorOptions;
  const Comp = xType === "timepicker" || type === "time" ? import_baseComponent.TimePicker : import_baseComponent.DatePicker;
  const { onKeyDown, ...newProps } = getEditorProps("date", defaultProps);
  return /* @__PURE__ */ React.createElement("div", { style: { width: "100%", height: "100%" }, onKeyDown }, /* @__PURE__ */ React.createElement(Comp, { ...newProps }));
}
function getDateProps(defaultProps) {
  const { editorOptions, value, outRef, onChange, onKeyDown } = defaultProps;
  const getPickerAndFormat = (type2) => {
    switch (type2) {
      case "datetime":
        return { f: "YYYY-MM-DD HH:mm:ss", p: "date" };
      case "time":
        return { f: "HH:mm:ss", p: type2 };
      case "year":
        return { f: "YYYY", p: type2 };
      case "quarter":
        return { f: "YYYY-[Q]Q", p: type2 };
      case "month":
        return { f: "YYYY-MM", p: type2 };
      case "week":
        return { f: "YYYY-wo", p: type2 };
      default:
        return { f: "YYYY-MM-DD", p: "date" };
    }
  };
  const { dateFormat, type, xType, props } = editorOptions;
  const pf = getPickerAndFormat(xType === "timepicker" ? "time" : type);
  delete props.type;
  return {
    defaultOpen: true,
    placeholder: dateFormat || pf.f,
    ...props,
    picker: pf.p,
    value,
    allowClear: true,
    autoComplete: "off",
    showTime: type === "datetime" || pf.p === "time",
    format: dateFormat || pf.f,
    onChange,
    onKeyDown(e) {
      var _a;
      const keyCodes = [9, 35, 36, 37, 39];
      outRef.current && (outRef.current.stopPropagation = keyCodes.includes(e.keyCode) ? false : (_a = outRef.current) == null ? void 0 : _a.getApi().isOpened());
      onKeyDown(e);
    }
  };
}
function HelpEditor(defaultProps) {
  const { type = "SingleHelp" } = defaultProps.editorOptions;
  const [Comp, props] = (0, import_util.getRegisterComponentWithProps)(type);
  if (!Comp) {
    console.warn(`${type} unregister`);
    return null;
  }
  defaultProps.editorOptions.type = defaultProps.editorOptions.type || type;
  return /* @__PURE__ */ React.createElement(Comp, { ...props, ...getEditorProps("help", defaultProps) });
}
function getHelpProps(defaultProps) {
  const {
    editorOptions,
    table,
    dataIndex,
    column: { valueType },
    value,
    row,
    outRef,
    onChange,
    onKeyDown
  } = defaultProps;
  const { valueField, labelField, clientSqlFilter, nameField, props, request, type, helpid: helpId } = editorOptions;
  const displayField = nameField || editorOptions.displayField || `${dataIndex}EXName`;
  const multiple = type === "MultipleHelp" ? true : type === "SingleHelp" ? false : editorOptions.multiple;
  const dealSqlFilter = () => {
    const sqlFilter = props.clientSqlFilter || clientSqlFilter;
    if (sqlFilter) {
      const exec = (expr) => {
        if (import_util.util.isString(expr) && /((\$D)|(\$R)|(\$V)|(\$DI))\./.test(expr)) {
          try {
            const fn = new Function("$D", "$R", "$V", "$DI", `return ${expr}`);
            return fn(table.getRows(), row, value, dataIndex) ?? expr;
          } catch (e) {
          }
        }
        return expr;
      };
      if (import_util.util.isFunction(sqlFilter)) {
        return (args) => sqlFilter({ helpId, ...args, ds: table.getRows(), row, value, dataIndex });
      } else if (import_util.util.isString(sqlFilter)) {
        return exec(sqlFilter);
      } else {
        return Object.keys(sqlFilter).reduce((p, k) => {
          return { ...p, [k]: exec(sqlFilter[k]) };
        }, {});
      }
    }
    return sqlFilter;
  };
  const newProps = {
    valueField,
    labelField: labelField || (nameField ? editorOptions.displayField : void 0),
    ...props,
    clientSqlFilter: dealSqlFilter(),
    request,
    helpId: helpId || editorOptions.helpId,
    value: getValueLabel({ row, value, valueType, nameField: displayField, multiple }),
    onInputKeyDown() {
      outRef.current && (outRef.current.stopPropagation = outRef.current.editing);
    },
    onChange(...args) {
      var _a;
      const api = (_a = outRef.current) == null ? void 0 : _a.getApi();
      if (api) {
        if (api.getText && dataIndex !== displayField) {
          row[displayField] = api.getText(",");
        }
        onChange();
      } else {
        onChange(...args);
      }
    },
    onOpenChange(open, type2) {
      table.setEditLock(open);
      if (type2 === "dropdown" && outRef.current) {
        outRef.current.editing = open;
      }
    },
    onKeyDown(e) {
      const keyCodes = [9, 35, 36, 37, 39];
      if (outRef.current && keyCodes.includes(e.keyCode)) {
        outRef.current.stopPropagation = false;
      }
      onKeyDown(e);
    }
  };
  if (!newProps.helpId) {
    delete newProps.helpId;
  }
  if (!newProps.valueField) {
    delete newProps.valueField;
  }
  if (!newProps.labelField) {
    delete newProps.labelField;
  }
  return newProps;
}
function getEditorProps(editType, defaultProps) {
  switch (editType) {
    case "help":
      return getHelpProps(defaultProps);
    case "date":
      return getDateProps(defaultProps);
    case "select":
      return getSelectProps(defaultProps);
    case "check":
      return getCheckProps(defaultProps);
    case "options":
      return getOptionsProps(defaultProps);
    default:
      return {};
  }
}
function Customized(allProps) {
  var _a;
  const { editorOptions, onChange, row, ...payload } = allProps;
  const {
    props: { ref, ...others },
    nameField,
    ...options
  } = editorOptions;
  const [Comp, defaultProps] = isElementType(options.xtype) ? [options.xtype, {}] : (0, import_util.getRegisterComponentWithProps)(options.xtype);
  const newProps = {
    ...defaultProps,
    ...payload,
    ...others,
    row,
    editorOptions: options,
    props(editType) {
      const tmp = getEditorProps(editType, { ...defaultProps, ...allProps });
      tmp.outRef = tmp.ref;
      return tmp;
    }
  };
  newProps.onChange = (value) => {
    if (import_util.util.isNullOrEmpty(value)) {
      nameField && (row[nameField] = "");
      onChange(value);
    } else {
      const multiple = editorOptions.multiple ?? import_util.util.isArray(value);
      if (multiple) {
        const arr = import_util.util.isArray(value) ? value : [value];
        const [values, labels] = [[], []];
        arr.forEach((v) => {
          if (import_util.util.isObject(v) && v.hasOwnProperty("value")) {
            values.push(v.value);
            labels.push(v.label);
          } else {
            values.push(v);
          }
        });
        nameField && (row[nameField] = labels.join(","));
        onChange(values);
      } else {
        nameField && (row[nameField] = value.label ?? "");
        onChange(value.value ?? value);
      }
    }
  };
  if (nameField) {
    newProps.value = getValueLabel({
      row,
      value: payload.value,
      valueType: (_a = payload.column) == null ? void 0 : _a.valueType,
      nameField,
      multiple: editorOptions.multiple ?? import_util.util.isArray(payload.value)
    });
  }
  return /* @__PURE__ */ React.createElement(Comp, { ...newProps });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  EditorFactory
});
